﻿using EquipSecs300;
using EquipSecs300.Parameter;
using SecsEquip;
using SecsEquip300;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EquipSecs300
{
    public class GEM_LoadPort : SecsEquipEx
    {
        public int m_nPortCount = SecsDataHelper.Function.PortQty;  // 初始化的时候设定好
        public Dictionary<string, GEM_LoadPortSub> MapPort = new Dictionary<string, GEM_LoadPortSub>();
        public Dictionary<int, PortInfo> PortInfo = new Dictionary<int, PortInfo>();

        public event Action CarrierInfoChangeHandler;
        public GEM_LoadPort(CSecsEquip300 m_pSecs, SecsEquipHelper secsEquipHelper)
        {
            base.m_pName = "Load Port";
            this.m_pSecs = m_pSecs;
            this.SecsEquipHelper = secsEquipHelper;

            InitPort();
            InitCtrl();
        }
        private void InitPort()
        {
            PortInfo = SecsDataHelper.PortInfo;
            for (int i = 1; i < m_nPortCount + 1; i++)
            {
                if (!PortInfo.ContainsKey(i))
                {
                    PortInfo.Add(i, new PortInfo());
                    Save();
                }
                else
                {
                    if (PortInfo[i] == null)
                    {
                        PortInfo[i] = new PortInfo();
                        Save();
                    }
                }

            }

        }
        private void Load_LoadPortInfo()
        {
            for (int i = 1; i < m_nPortCount + 1; i++)
            {
                if (PortInfo[i] != null)
                {
                    MapPort[$"Port_{i}"].CarrierID = PortInfo[i].CarrierID;
                    MapPort[$"Port_{i}"].MapSlotResult = PortInfo[i].MapSlotResult;
                }
            }

        }
        // 更新数据
        public override void UpdateData()
        {
            m_pSecs.m_pCMSTransferStateChange += OnCMSTransferStateChangeProc;
            m_pSecs.m_pCMSCarrierIDStatusChange += OnCmsCarrierIDStatus;
            m_pSecs.m_pCMSCarrierSlotMapStatusChange += OnCmsCarrierSlotMapStatus;
            SecsEquipHelper.RemoteContro.m_pCMSCarrierSlotMapStatusChange += OnCmsCarrierSlotMapStatus;

            SecsEquipHelper.RemoteContro.SeAcceptCassette += ONAccepCarrierIDStatus;
            SecsEquipHelper.RemoteContro.SeRejectCassette += ONRejectCarrierIDStatus;
            SecsEquipHelper.RemoteContro.SeSelectPPID += ONGetPPID;
            SecsEquipHelper.RemoteContro.SeStart += ONStartForEap;
            Load_LoadPortInfo();
        }

        void InitCtrl()
        {
            // 添加SubPort
            for (int i = 1; i <= m_nPortCount; i++)
            {
                string pName = "Port_" + i.ToString();
                GEM_LoadPortSub portSub = new GEM_LoadPortSub(this, SecsEquipHelper);
                portSub.SetPortNo(i);
                portSub.UpdateData();
                AddToList(pName, portSub);
            }
        }

        // 添加数据
        void AddToList(string name, GEM_LoadPortSub portSub)
        {
            InitSub(portSub);
            MapPort.Add(name, portSub);
        }

        // 初始化
        private void InitSub(GEM_LoadPortSub portSub)
        {
            portSub.m_pMain = this;
            portSub.m_pSecs = m_pSecs;
            portSub.SecsEquipHelper = SecsEquipHelper;
        }

        // 寻找相应的map数据
        GEM_LoadPortSub GetPortSubForMap(string name)
        {
            GEM_LoadPortSub portSub = null;
            try
            {
                portSub = MapPort[name];
            }
            catch (System.Exception)
            {
                portSub = null;
            }
            return portSub;
        }

        // 响应事件

        /// <summary>
        /// 响应Load Port状态改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="nPort"></param>
        /// <param name="nState"></param>
        void OnCMSTransferStateChangeProc(object sender, int nPort, LoadPortTransferState nState)
        {
            foreach (GEM_LoadPortSub loadPortSub in MapPort.Values)
            {
                if (loadPortSub.GetPortNo() == nPort)
                {
                    loadPortSub.OnCMSTransferStateChangeProc(sender, nPort, nState);
                    LogPortBaseMsg($"TransferState-> Port{nPort}, State = {nState.ToString()}");
                }
            }
        }

        /// <summary>
        /// 等待主机确认 CarrierID  状态改变  
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="nPort"></param>
        /// <param name="pCarrierID"></param>
        /// <param name="nState"></param>
        public void OnCmsCarrierIDStatus(object sender, int nPort, string pCarrierID, CarrierIDStatus nState)
        {
            foreach (GEM_LoadPortSub loadPortSub in MapPort.Values)
            {
                if (loadPortSub.GetPortNo() == nPort)
                {
                    loadPortSub.OnCmsCarrierIDStatus(sender, nPort, pCarrierID, nState);
                    LogPortBaseMsg($"CarrierIDStatus-> Port{nPort}, CarrierID = {pCarrierID}, State = {nState.ToString()}");
                }
            }
        }

        /// <summary>
        /// 等待主机确认 Slot 状态改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="nPort"></param>
        /// <param name="pCarrier"></param>
        void OnCmsCarrierSlotMapStatus(object sender, int nPort, Carrier pCarrier)
        {
            foreach (GEM_LoadPortSub loadPortSub in MapPort.Values)
            {
                if (loadPortSub.GetPortNo() == nPort)
                {
                    loadPortSub.OnCmsCarrierSlotMapStatus(sender, nPort, pCarrier);
                    AddCarrierInfo(nPort, pCarrier);
                    LogPortBaseMsg($"CarrierSlotMapStatus-> Port{nPort}, CarrierID = {pCarrier.pCarrierID}, State = {pCarrier.nSlotMapStatus.ToString()}");
                    LogPortBaseMsg(Environment.NewLine + LogCarrierInfo(pCarrier));
                }
            }
        }

        /// <summary>
        /// 保存Carrier信息到本地
        /// </summary>
        /// <param name="nPort"></param>
        /// <param name="pCarrier"></param>
        private void AddCarrierInfo(int nPort, Carrier pCarrier)
        {
            if (PortInfo.ContainsKey(nPort))
            {
                PortInfo[nPort].CarrierInfo = pCarrier;
            }
            else
            {
                PortInfo.Add(nPort, new PortInfo { CarrierInfo = pCarrier });
            }

            Save();
        }

        public void Save()
        {
            SecsDataHelper.PortInfoDAL.Save(PortInfo);
            CarrierInfoChangeHandler?.Invoke();
        }

        public REMOTE_REPLY_KE ONAccepCarrierIDStatus(string pPortID)
        {
            int nPort = UtilitiesConvert.StringToInt32(pPortID);
            foreach (GEM_LoadPortSub pView in MapPort.Values)
            {
                if (pView.GetPortNo() == nPort)
                {
                    return pView.ONAccepCarrierIDStatus(pPortID);
                }
            }
            return REMOTE_REPLY_KE.eCOMMAND_OTHER;
        }

        public REMOTE_REPLY_KE ONRejectCarrierIDStatus(string pPortID)
        {
            int nPort = UtilitiesConvert.StringToInt32(pPortID);
            foreach (GEM_LoadPortSub pView in MapPort.Values)
            {
                if (pView.GetPortNo() == nPort)
                {
                    return pView.ONRejectCarrierIDStatus(pPortID);
                }
            }
            return REMOTE_REPLY_KE.eCOMMAND_OTHER;
        }
        public REMOTE_REPLY_KE ONGetPPID(string pPortID, string pRecipeName, string pLotName)
        {
            int nPort = UtilitiesConvert.StringToInt32(pPortID);
            foreach (GEM_LoadPortSub pView in MapPort.Values)
            {
                if (pView.GetPortNo() == nPort)
                {
                    return pView.ONGetPPID(pRecipeName, pLotName);
                }
            }
            return REMOTE_REPLY_KE.eCOMMAND_OTHER;
        }
        public REMOTE_REPLY_KE ONStartForEap(string pPortID)
        {
            int nPort = UtilitiesConvert.StringToInt32(pPortID);
            foreach (GEM_LoadPortSub pView in MapPort.Values)
            {
                if (pView.GetPortNo() == nPort)
                {
                    return pView.ONStartForEap(pPortID);
                }
            }
            return REMOTE_REPLY_KE.eCOMMAND_OTHER;
        }

        private string LogCarrierInfo(Carrier pCarrier)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < pCarrier.pSlotData.Length; i++)
            {
                sb.AppendLine("\t"
                 + "nSlot = " + pCarrier.pSlotData[i].nSlot + " , "
                + "nSlotMapEnum = " + pCarrier.pSlotData[i].nSlotMapEnum.ToString() + " , "
                + "pLotID = " + pCarrier.pSlotData[i].pLotID + " , "
                + "pSubstrateID = " + pCarrier.pSlotData[i].pSubstrateID + " , "
                + "nProcessState = " + pCarrier.pSlotData[i].nProcessState + " ; ");
            }
            string str = sb.ToString();
            return sb.ToString();

        }
        private void LogPortBaseMsg(string strLog)
        {
            string str = "LoadPort: " + strLog;
            LogMsg(str);
        }
    }

}
